package com.aqumon.www.service.impl;

import com.aqumon.www.entity.dto.JenkinsBuildInfoDto;
import com.aqumon.www.entity.persistent.JenkinsConfig;
import com.aqumon.www.entity.persistent.Script;
import com.aqumon.www.entity.request.jenkins.JobBasicReq;
import com.aqumon.www.entity.request.scripts.ScriptCreateReq;
import com.aqumon.www.entity.request.scripts.ScriptDelReq;
import com.aqumon.www.entity.request.scripts.ScriptEditReq;
import com.aqumon.www.entity.response.scrip.ScriptListResp;
import com.aqumon.www.mapper.JenkinsConfigMapper;
import com.aqumon.www.mapper.ScriptMapper;
import com.aqumon.www.service.JenkinsBuildService;
import com.aqumon.www.service.ScriptService;
import com.aqumon.www.util.JenkinsUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.model.JobWithDetails;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * jenkins job 列表 服务实现类
 * </p>
 *
 * @author aqumon
 * @since 2022-05-19
 */
@Service
public class ScriptServiceImpl extends ServiceImpl<ScriptMapper, Script> implements ScriptService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ScriptServiceImpl.class);

    @Resource
    ScriptMapper scriptMapper;

    @Resource
    JenkinsConfigMapper jenkinsConfigMapper;

    @Resource
    JenkinsBuildService jenkinsBuildService;

    public JobWithDetails getJob(JenkinsConfig jenkinsConfig, String jobFullName){
        JenkinsServer jenkinsServer = JenkinsUtil.connection(jenkinsConfig);
        try {
            // 获取 Job 信息
            return jenkinsServer.getJob(jobFullName);
        } catch (IOException e) {
            LOGGER.warn("获取jenkins jobWithDetails 异常:" + e);
            return null;
        }
    }

    @Override
    public boolean createScript(ScriptCreateReq scriptCreateReq) {
        String jenkinsName = scriptCreateReq.getJenkinsName();
        String jobFullName = scriptCreateReq.getJobFullName();
        Script script =  new Script(null);
        script.setScriptName(scriptCreateReq.getScriptName());
        script.setCodeRepository(scriptCreateReq.getCodeRepository());
        script.setDescription(scriptCreateReq.getDescription());
        script.setProduct(scriptCreateReq.getProduct());
        script.setModule(scriptCreateReq.getModule());
        if (jenkinsName == null || jenkinsName.length() <= 0) {
            script.setJenkinsId(-1L);
        } else {
            script.setJenkinsId(jenkinsConfigMapper.selectByJenkinsName(jenkinsName).getId());
        }
        script.setJobFullName(jobFullName);
        script.setGmtCreated(new Date());
        return scriptMapper.insert(script) > 0;
    }

    @Override
    public Script editScript(ScriptEditReq scriptEditReq) {
        String jenkinsName = scriptEditReq.getJenkinsName();
        String jobFullName = scriptEditReq.getJobFullName();
        Script script =  new Script(scriptEditReq.getId());
        script.setScriptName(scriptEditReq.getScriptName());
        script.setCodeRepository(scriptEditReq.getCodeRepository());
        script.setDescription(scriptEditReq.getDescription());
        script.setProduct(scriptEditReq.getProduct());
        script.setModule(scriptEditReq.getModule());
        script.setJenkinsId(jenkinsConfigMapper.selectByJenkinsName(jenkinsName).getId());
        script.setJobFullName(jobFullName);
        script.setGmtModified(new Date());
        if (scriptMapper.updateById(script) > 0) {
            return script;
        } else return new Script(scriptEditReq.getId());
    }

    @Override
    public boolean deleteJob(JobBasicReq jobBasicReq) {
        String jobName = jobBasicReq.getJobFullName();
        JenkinsConfig jenkinsConfig = jenkinsConfigMapper.selectByJenkinsName(jobBasicReq.getJenkinsName());
        JenkinsServer jenkinsServer = JenkinsUtil.connection(jenkinsConfig);
        try {
            jenkinsServer.deleteJob(jobName);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public boolean deleteScript(ScriptDelReq scriptDelReq) {
        return scriptMapper.deleteById(scriptDelReq.getId()) > 0;
    }

    @Override
    public List<ScriptListResp> listAllScripts(Long jenkinsId) {
        List<ScriptListResp> scriptListResp = new ArrayList<>();
        List<Script> scriptList = scriptMapper.listAllScript(jenkinsId);
        for (Script script: scriptList) {
            ScriptListResp scriptResp = new ScriptListResp();
            scriptResp.setScriptId(script.getId());
            scriptResp.setScriptName(script.getScriptName());
            scriptResp.setCodeRepository(script.getCodeRepository());
            scriptResp.setDescription(script.getDescription());
            scriptResp.setProduct(script.getProduct());
            scriptResp.setModule(script.getModule());
            scriptResp.setLastBuildStatus(script.getLastBuildStatus());
            scriptResp.setLastBuildTime(script.getLastBuildTime());
            Long scriptJenkinsId = script.getJenkinsId();
            if (scriptJenkinsId == null || scriptJenkinsId == -1L) {
                LOGGER.warn("scriptJenkinsId 非法: " + scriptJenkinsId);
            } else {
                JenkinsConfig jenkinsConfig = jenkinsConfigMapper.selectById(scriptJenkinsId);
                try {
                    JobWithDetails jobWithDetails = getJob(jenkinsConfig, script.getJobFullName());
                    scriptResp.setJobFullUrl(jobWithDetails.getUrl());
                    JenkinsBuildInfoDto lastBuildInfo = jenkinsBuildService.getLastBuildInfo(jenkinsConfig, script.getJobFullName());
                    scriptResp.setLastBuildStatus(lastBuildInfo.getBuildStatus());
                    scriptResp.setLastBuildTime(lastBuildInfo.getBuildTime());
                    scriptResp.setDuration(lastBuildInfo.getDuration());
                } catch (NullPointerException e)
                {
                    LOGGER.warn("获取脚本配置的jenkins job 信息异常:" + script);
                    scriptResp.setJobFullUrl("");
                } finally {
                    scriptResp.setJenkinsName(jenkinsConfig.getJenkinsName());
                    scriptResp.setJenkinsUrl(jenkinsConfig.getJenkinsUrl());
                    scriptResp.setJobFullName(script.getJobFullName());
                }
            }
            scriptListResp.add(scriptResp);
        }
        return scriptListResp;
    }
}
